package serial

import (
	"encoding/hex"
	"fmt"
	"github.com/tarm/serial"
	"iot-protocol-oob/codec/decoder"
)

var (
	port *serial.Port
)

type ModbusRTUSerialPort struct {
	PortName string
	Baud     int
	StopBits serial.StopBits
	Port     *serial.Port
}

func (m *ModbusRTUSerialPort) Open() {
	config := &serial.Config{
		Name:     m.PortName,
		Baud:     m.Baud,
		StopBits: m.StopBits,
	}
	var err error
	port, err = serial.OpenPort(config)
	if err != nil {
		fmt.Println("open serial port err")
	}
	if port == nil {
		fmt.Println("open serial port err port is nil")
	}
	fmt.Println("open serial port ok")
	defer func(port *serial.Port) {
		err := port.Close()
		if err != nil {
			fmt.Sprintf("串口关闭失败")
		}
	}(port)
	m.Port = port
	go Receive()
}

func (m *ModbusRTUSerialPort) Write(byt []byte) (int, error) {

	i, err := m.Port.Write(byt)
	if err != nil {
		fmt.Println("serial port write err " + err.Error())
		return i, err
	}
	fmt.Printf("serial port write ok %d", i)
	return i, err
}

func Receive() {

	buf := make([]byte, 1)
	Cache := make([]byte, 0)
	for {
		read, err := port.Read(buf)
		if err != nil {
			fmt.Printf("serial port read err %s", err.Error())
			println()
		}
		if read > 0 {
			decode, c := decoder.ModbusRTUDecoder{Buf: buf[:read], Cache: Cache}.Decode()
			Cache = c
			if len(decode) != 0 {
				toString := hex.EncodeToString(decode)
				fmt.Printf("serial port read ok %s", toString)
				println()
			}
		}
	}
}
